package org.jparrow.framework;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jparrow.framework.bean.Data;
import org.jparrow.framework.bean.Handler;
import org.jparrow.framework.bean.Param;
import org.jparrow.framework.bean.View;
import org.jparrow.framework.helper.BeanHelper;
import org.jparrow.framework.helper.ConfigHelper;
import org.jparrow.framework.helper.ControllerHelper;
import org.jparrow.framework.util.ArrayUtil;
import org.jparrow.framework.util.CodecUtil;
import org.jparrow.framework.util.JsonUtil;
import org.jparrow.framework.util.ReflectionUtil;
import org.jparrow.framework.util.StreamUtil;
import org.jparrow.framework.util.StringUtil;

/**
 * 请求转发器
 * 
 * @author supda
 * @date 2017-3-26
 *
 */
@WebServlet(urlPatterns="/*", loadOnStartup = 0)
public class DispatcherServlet extends HttpServlet{

	/**
	 * 1.DispatcherServlet启动，拦截所有请求，转发到对应的处理器上
	 * 2.ClassHelper加载指定包下的所有的类
	 * 3.BeanHelper创建Bean与Bean实例的映射关系
	 * 4.IOCHelper依赖注入Service的实例
	 * 5.ControllerHelper创建请求与处理方法的映射关系
	 */
	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		super.init(servletConfig);
		//初始化相关Helper类
		HelperLoader.init();
		//获取ServletContext对象（用于注册Servlet）
		ServletContext servletContext = servletConfig.getServletContext();
		//注册处理JSP的Servlet
		ServletRegistration jspServlet = servletContext.getServletRegistration("jsp");
		jspServlet.addMapping(ConfigHelper.getAppJspPath()+"*");
		//注册处理静态资源的默认Servlet
		ServletRegistration defaultServlet = servletContext.getServletRegistration("default");
		defaultServlet.addMapping(ConfigHelper.getAppAssetPath()+"*");
	}
	
	/**
	 * 转发所用请求，反射执行指定的处理器，返回指定参数。
	 */
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取请求方法与请求路径
		String requestMethod = request.getMethod().toLowerCase();
		String requestPath = request.getPathInfo();
		
		System.out.println("请求method:"+requestMethod+",请求路径:"+requestPath);
		
		//获取Action处理器
		Handler handler = ControllerHelper.getHandler(requestMethod, requestPath);
		if(handler != null) {
			//获取Controller类及其Bean实例
			Class<?> controllerClass = handler.getControllerClass();
			//若存在代理，此处拿到的是代理对象。
			Object controllerBean = BeanHelper.getBean(controllerClass);
			System.out.println("controllerBean:"+controllerBean);
			//创建请求参数对象
			Map<String, Object> paramMap = new HashMap<String, Object>();
			Enumeration<String> paramNames = request.getParameterNames();
			while(paramNames.hasMoreElements()) {
				String paramName = paramNames.nextElement();
				String paramValue = request.getParameter(paramName);
				paramMap.put(paramName, paramValue);
			}
			String body = CodecUtil.decodeURL(StreamUtil.getString(request.getInputStream()));
			if(StringUtil.isNotEmpty(body)) {
				String[] params = StringUtil.splitString(body, "&");
				if(ArrayUtil.isNotEmpty(params)) {
					for(String param : params){
						String[] array = StringUtil.splitString(param, "=");
						if(ArrayUtil.isNotEmpty(array) && array.length == 2){
							String paramName = array[0];
							String paramValue = array[1];
							paramMap.put(paramName, paramValue);
						}
					}
				}
			}
			Param param = new Param(paramMap);
			//调用Action方法
			Method actionMethod = handler.getActionMethod();
			Object result = ReflectionUtil.invokeMethod(controllerBean, actionMethod, param);
			//处理Action方法返回值
			if(result instanceof View) {
				//返回JSP页面
				View view = (View) result;
				String path = view.getPath();
				if(StringUtil.isNotEmpty(path)) {
					if(path.startsWith("/")){
						response.sendRedirect(request.getContextPath()+path);
					}else{
						Map<String, Object> model = view.getModel();
						for(Map.Entry<String, Object> entry : model.entrySet()){
							request.setAttribute(entry.getKey(), entry.getValue());
						}
						request.getRequestDispatcher(ConfigHelper.getAppJspPath()+path)
							.forward(request, response);
					}
				}else if(result instanceof Data){
					//返回JSON数据
					Data data = (Data)result;
					Object model = data.getModel();
					if(model != null) {
						response.setContentType("application/json");
						response.setCharacterEncoding("UTF-8");
						PrintWriter writer = response.getWriter();
						String json = JsonUtil.toJson(model);
						writer.write(json);
						writer.flush();
						writer.close();
					}
				}
			}
		}
		
		
	}

	
}
